package cn.com.infcn.spider.web.collector;

import java.util.Date;
import java.util.List;

import org.eclipse.jetty.server.Request;
import org.nlpcn.commons.lang.util.StringUtil;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.Mvcs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;

import com.alibaba.fastjson.JSONObject;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;

import cn.com.infcn.spider.SchedulerManager;
import cn.com.infcn.spider.URIManager;
import cn.com.infcn.spider.domain.DataJob;
import cn.com.infcn.spider.domain.DirectoryJob;
import cn.com.infcn.spider.domain.FtpJob;
import cn.com.infcn.spider.domain.HttpJob;
import cn.com.infcn.spider.domain.Job;
import cn.com.infcn.spider.util.ExceptionUtil;
import cn.com.infcn.spider.util.MongoDao;
import cn.com.infcn.spider.util.StaticValue;

@IocBean
public class JobAction {

	@Inject
	private MongoDao mongoDao;

	/**
	 * job列表页
	 * 
	 * @param limit
	 *            从第几条开始
	 * @param size
	 *            每页显示多少条
	 * @param filter
	 *            过滤条件
	 * @param request
	 *            请求
	 */
	@At("/admin/job/list")
	@Ok("jsp:/job_list.jsp")
	public Object list(@Param("page") int page, @Param("rows") int rows, @Param("filter") String filterStr, Request request) {

		int size = rows;
		int skip = (page - 1) * rows;
		BasicDBObject filter = new BasicDBObject();
		if (StringUtil.isNotBlank(filterStr)) {
			filter = new BasicDBObject(JSONObject.parseObject(filterStr));
			request.setAttribute("_jobType", filter.getString("jobType"));
		}

		if (size <= 0) {
			size = 20;
		}

		JSONObject result = new JSONObject();

		try (DBCursor find = mongoDao.getCollection("job").find(filter)) {

			List<DBObject> list = find.skip(skip).limit(size).toArray();

			for (DBObject dbObject : list) {
				dbObject.put("statusStr", Job.status2Str(dbObject.get("status")));
			}
			result.put("records", find.count());// 总记录数
			result.put("rows", list);// 数据

		}

		result.put("page", page);// 当前页码
		return result;

	}

	/**
	 * 保存一个job
	 * 
	 * @param json
	 * @return
	 */
	@At("/admin/job/http/save_or_update")
	@Ok("json")
	public Object httpJobSave(@Param("..") HttpJob obj) {
		return _save(obj);
	}

	/**
	 * ceshi一个job
	 * 
	 * @param json
	 * @return
	 */
	@At("/admin/job/http/test")
	@Ok("json")
	public Object httpJobTest(@Param("..") HttpJob obj, @Param("uri") String uri) {
		return _test(obj, uri);
	}

	/**
	 * 保存一个job
	 * 
	 * @param json
	 * @return
	 */
	@At("/admin/job/data/save_or_update")
	@Ok("json")
	public Object dataJobSave(@Param("..") DataJob obj) {
		return _save(obj);
	}

	private Object _test(Job obj, String uri) {
		try {
			String jsonString = JSONObject.toJSONString(obj.instanceScheduler().test(uri)) ;
			return StaticValue.okMessageJson(jsonString);
		} catch (Exception e) {
			e.printStackTrace();
			return StaticValue.errMessageJson(ExceptionUtil.printStackTrace(e));
		}
	}

	private Object _save(Job obj) {

		JSONObject job = (JSONObject) JSONObject.toJSON(obj);

		String jobName = job.getString("name");
		
		if(StringUtil.isBlank(jobName)){
			return StaticValue.errMessageJson("jobName can not named empty or null !");
		}

		if (jobName.equals("job")) {
			return StaticValue.errMessageJson("jobName can not named it !");
		}

		DBObject findById = mongoDao.findById("job", jobName);

		if (findById != null && !findById.get("_id").equals(job.get("_id"))) {
			return StaticValue.errMessageJson(jobName + " alread in db!");
		}

		if (findById != null) {
			findById.putAll(job);
			findById.put("updateTime", new Date());
			mongoDao.save("job", findById);
		} else {
			job.put("_id", jobName);
			job.put("updateTime", new Date());
			job.put("createTime", new Date());
			mongoDao.save("job", job);
		}

		try {
			SchedulerManager.flush(jobName);
		} catch (InterruptedException e) {
			return StaticValue.errMessageJson(e);
		}

		return StaticValue.okMessageJson("保存成功 ！");

	}

	/**
	 * 删除一个job
	 * 
	 * @param json
	 * @return
	 */
	@At("/admin/job/drop/?")
	@Ok("json")
	public Object drop(String jobName) {

		DBObject findById = mongoDao.findById("job", jobName);

		if (findById == null) {
			return StaticValue.errMessageJson(jobName + " not find in db!");
		}

		findById.put("status", -1);
		findById.put("updateTime", new Date());

		mongoDao.save("job", findById);

		try {
			SchedulerManager.flush(jobName);
		} catch (InterruptedException e) {
			return StaticValue.errMessageJson(e);
		}

		return StaticValue.OK_J;

	}

	/**
	 * 新建一个job
	 * 
	 * @param json
	 * @return
	 */
	@At("/admin/job/new/?")
	@Ok("jsp:/job_editor.jsp")
	public Object newJob(String jobType) {

		Mvcs.getReq().setAttribute("_jobType", jobType);

		return null;

	}

	/**
	 * 查询一个job
	 * 
	 * @param json
	 * @return
	 */
	@At("/admin/job/get/?")
	@Ok("jsp:/job_editor.jsp")
	public Object get(String jobName) {

		DBObject findById = mongoDao.findById("job", jobName);

		if (findById == null) {
			return StaticValue.errMessageJson(jobName + " not find in db!");
		}
		findById.put("statusStr", Job.status2Str(findById.get("status")));

		Mvcs.getReq().setAttribute("_jobType", findById.get("jobType"));

		return findById;

	}

	@At("/admin/job/reset/?")
	@Ok("json")
	public Object reset(String jobName) {
		try {
			URIManager.drop(jobName);
			return StaticValue.OK_J;
		} catch (Exception e) {
			e.printStackTrace();
			return StaticValue.errMessageJson(e);
		}
	}
	
	/**
	 * 保存一个job
	 * 
	 * @param json
	 * @return
	 */
	@At("/admin/job/directory/save_or_update")
	@Ok("json")
	public Object directoryJobSave(@Param("..") DirectoryJob obj) {
		return _save(obj);
	}
	
	/**
	 * 保存一个job
	 * 
	 * @param json
	 * @return
	 */
	@At("/admin/job/ftp/save_or_update")
	@Ok("json")
	public Object ftpJobSave(@Param("..") FtpJob obj) {
		return _save(obj);
	}

}
